namespace TSL.Utility.Json
{
    using System;
    using System.Globalization;
    using System.Text;

    public class PrimitiveConverter : IJavaScriptConverter
    {
        public PrimitiveConverter()
        {
            base.m_serializableTypes = new Type[] { typeof(bool), typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(double), typeof(float) };
            base.m_deserializableTypes = base.m_serializableTypes;
        }

        public override object Deserialize(IJavaScriptObject o, Type t)
        {
            if (!t.IsPrimitive)
            {
                throw new NotSupportedException();
            }
            switch (Type.GetTypeCode(t))
            {
                case TypeCode.Boolean:
                    return (bool) ((JavaScriptBoolean) o);

                case TypeCode.SByte:
                    return sbyte.Parse(o.ToString());

                case TypeCode.Byte:
                    return byte.Parse(o.ToString());

                case TypeCode.Int16:
                    return short.Parse(o.ToString());

                case TypeCode.UInt16:
                    return ushort.Parse(o.ToString());

                case TypeCode.Int32:
                    return int.Parse(o.ToString());

                case TypeCode.UInt32:
                    return uint.Parse(o.ToString());

                case TypeCode.Int64:
                    return long.Parse(o.ToString());

                case TypeCode.UInt64:
                    return ulong.Parse(o.ToString());

                case TypeCode.Single:
                    return float.Parse(o.ToString().Replace(".", NumberFormatInfo.CurrentInfo.NumberDecimalSeparator));

                case TypeCode.Double:
                    return double.Parse(o.ToString().Replace(".", NumberFormatInfo.CurrentInfo.NumberDecimalSeparator));
            }
            throw new NotImplementedException("This primitive data type '" + t.FullName + "' is not implemented.");
        }

        public override string Serialize(object o)
        {
            StringBuilder sb = new StringBuilder();
            this.Serialize(o, sb);
            return sb.ToString();
        }

        public override void Serialize(object o, StringBuilder sb)
        {
            if (o is bool)
            {
                if ((bool) o)
                {
                    sb.Append("true");
                }
                else
                {
                    sb.Append("false");
                }
            }
            else if (o is float)
            {
                sb.Append(((float) o).ToString(null, CultureInfo.InvariantCulture));
            }
            else if (o is double)
            {
                sb.Append(((double) o).ToString(null, CultureInfo.InvariantCulture));
            }
            else
            {
                sb.Append(o.ToString());
            }
        }
    }
}

